package com.platform.api;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.platform.annotation.IgnoreAuth;
import com.platform.entity.GoodsEntity;
import com.platform.entity.OrderEntity;
import com.platform.entity.UserEntity;
import com.platform.entity.UserMsgEntity;
import com.platform.service.GoodsService;
import com.platform.service.OrderService;
import com.platform.service.UserMsgService;
import com.platform.util.ApiBaseAction;
import com.platform.utils.R;
import com.platform.utils.RRException;
import com.platform.utils.RequestUtil;
import com.platform.utils.ResourceUtil;
import com.platform.wx.mp.config.WxPayConfiguration;

import io.swagger.annotations.Api;

@Api(tags = "API支付相关接口")
@RestController
@RequestMapping("/api/pay")
public class ApiPayController extends ApiBaseAction {
    @Autowired
    private OrderService orderService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private UserMsgService userMsgService;
	
    @Autowired
    private WxPayConfiguration wxPayConfiguration;
	
    /**
     * 虚拟类、文章、视频、音频等商品 可直接支付
     * @param goodsId
     * @param params
     * @param map
     * @param request
     * @param resp
     * @return
     */
    @RequestMapping("/wx/{mpId}/goods/{goodsId}/{goodsNum}")
    public R wxPayFromGoods(@PathVariable("mpId") Integer mpId,
    		@PathVariable("goodsId") Integer goodsId,
    		@PathVariable("goodsNum") Integer goodsNum,
    		HttpServletRequest request,
    		HttpServletResponse resp) {
    	String orderNo = "";
        try {
        	GoodsEntity goods = goodsService.queryObject(goodsId);
        	UserEntity user = getCurrentUser();
        	if(goods.isPrivilege()) {
        		goodsNum = 1;
        	}
        	String orderType = "7";
        	if(goods.getGoodsType().equals(99)) {
        		orderType = "8";
        	}
        	if(goods.getId().equals(0)) {
        		orderType = "9";
        	}
        	OrderEntity orderInfo = orderService.newSaveByGoods(user,user.getParentId(),null,goodsId,goodsNum,orderType);
        	orderNo = orderInfo.getId().toString();
        	String openId = user.getWeixinOpenid();
        	if(StringUtils.isNotBlank(user.getWeixinUnionid())) {
    		    Map<String,Object> params = new HashMap<String,Object>();
    		    params.put("appId", mpId);
    		    params.put("unionId", user.getWeixinUnionid());
            	List<UserMsgEntity> userMsgs = userMsgService.queryList(params);
            	if(userMsgs.size() > 0) {
            		openId = userMsgs.get(0).getOpenId();
            	}
        	}
			WxPayMpOrderResult wxOrder = genWxPayOrder(mpId,orderInfo,RequestUtil.getClientIp(request),openId);
			R result = R.ok().put("wxOrder", wxOrder).put("pay_result", "success").put("pay_type", "wx");
			return result;
        }catch(RRException e) {
        	return R.error(500, e.getMessage());
        } catch (Exception e) {
        	logger.error("微信支付失败！订单号：" + orderNo +",原因:"+e.getMessage(),e);
        	return R.error(500, e.getMessage());
        }
    }

    /**
     * 支付
     */
    @RequestMapping("/wx/{mpId}/order/{orderId}")
    public R wxPayFromGoods(@PathVariable("mpId") Integer mpId,
    		@PathVariable("orderId") Integer orderId,
    		HttpServletRequest request,
    		HttpServletResponse resp) {
    	String orderNo = "";
        try {
        	UserEntity user = getCurrentUser();
        	OrderEntity orderInfo = orderService.queryObject(orderId);
        	String remark = request.getParameter("remark");
        	if(remark != null && remark.equals(orderInfo.getRemark())) {
        		orderService.updateRemark(orderId, remark, user.getId());
        	}
        	orderNo = orderInfo.getId().toString();
        	String openId = user.getWeixinOpenid();
        	if(StringUtils.isNotBlank(user.getWeixinUnionid())) {
    		    Map<String,Object> params = new HashMap<String,Object>();
    		    params.put("appId", mpId);
    		    params.put("unionId", user.getWeixinUnionid());
            	List<UserMsgEntity> userMsgs = userMsgService.queryList(params);
            	if(userMsgs.size() > 0) {
            		openId = userMsgs.get(0).getOpenId();
            	}
        	}
			WxPayMpOrderResult wxOrder = genWxPayOrder(mpId,orderInfo,RequestUtil.getClientIp(request),openId);
			R result = R.ok().put("wxOrder", wxOrder).put("pay_result", "success").put("pay_type", "wx");
			return result;
        }catch(RRException e) {
        	return R.error(500, e.getMessage());
        } catch (Exception e) {
        	logger.error("微信支付失败！订单号：" + orderNo +",原因:"+e.getMessage(),e);
        	return R.error(500, e.getMessage());
        }
    }

    /**
     * 虚拟类、文章、视频、音频等商品  未使用
     * @param goodsId
     * @param params
     * @param map
     * @param request
     * @param resp
     * @return
     */
    @RequestMapping("/wx/{mpId}/toforevervip")
    public R toForeverVip(@PathVariable("mpId") Integer mpId,
    		HttpServletRequest request,
    		HttpServletResponse resp) {
    	String orderNo = "";
        try {
        	UserEntity user = getCurrentUser();
        	OrderEntity orderInfo = orderService.toForeverVip(user);
        	orderNo = orderInfo.getId().toString();
        	String openId = user.getWeixinOpenid();
        	if(StringUtils.isNotBlank(user.getWeixinUnionid())) {
    		    Map<String,Object> params = new HashMap<String,Object>();
    		    params.put("appId", mpId);
    		    params.put("unionId", user.getWeixinUnionid());
            	List<UserMsgEntity> userMsgs = userMsgService.queryList(params);
            	if(userMsgs.size() > 0) {
            		openId = userMsgs.get(0).getOpenId();
            	}
        	}
        	
			WxPayMpOrderResult wxOrder = genWxPayOrder(mpId,orderInfo,RequestUtil.getClientIp(request),openId);
			R result = R.ok().put("wxOrder", wxOrder).put("pay_result", "fail").put("pay_type", "wx");
			return result;
        }catch(RRException e) {
        	return R.error(500, e.getMessage());
        } catch (Exception e) {
        	logger.error("微信支付失败！订单号：" + orderNo +",原因:"+e.getMessage(),e);
        	return R.error(500, e.getMessage());
        }
    }

    private WxPayMpOrderResult genWxPayOrder(Integer mpId,OrderEntity orderInfo,String ip,String wxOpenId) throws WxPayException{
    	try {
	    	WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
	      	orderRequest.setBody(orderInfo.getOrderGoodsName());
	      	orderRequest.setOutTradeNo(orderInfo.getId().toString());
		    orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(orderInfo.getActualPrice().toString()));//元转成分
		    orderRequest.setOpenid(wxOpenId);
		    orderRequest.setSpbillCreateIp(ip);
		    orderRequest.setTradeType(WxPayConstants.TradeType.JSAPI);
		    //	      //商户号
		    //	      orderRequest.setAttach("xxx公司");
		    // 支付成功后跳转页面  这里需要对url进行编码
		    orderRequest.setNotifyUrl(ResourceUtil.getConfigByName("wx.api.notifyUrl") + mpId);
		    WxPayMpOrderResult wxOrder = wxPayConfiguration.getPayService(mpId).createOrder(orderRequest);
			return wxOrder;
    	}catch(WxPayException e) {
    		throw new WxPayException("生成微信账单异常：",e);
    	}
    }

    @IgnoreAuth
    @PostMapping("/wx/notify/{mpId}")
    public String parseOrderNotifyResult(
    		@PathVariable("mpId") Integer mpId,
    		@RequestBody String xmlData) throws WxPayException {
      final WxPayOrderNotifyResult notifyResult = wxPayConfiguration.getPayService(mpId).parseOrderNotifyResult(xmlData);
      orderService.payNotify(notifyResult);
      return WxPayNotifyResponse.success("成功");
    }

}
